package com.sicilin.system.role.service;

import com.sicilin.common.exception.BusinessException;
import com.sicilin.common.exception.ServiceException;
import com.sicilin.common.page.PageObject;
import com.sicilin.common.page.PageUtils;
import com.sicilin.dao.AuthDao;
import com.sicilin.dao.RoleDao;
import com.sicilin.po.TSysAuth;
import com.sicilin.po.TSysRole;
import com.sicilin.po.TSysRoleAuth;
import com.sicilin.system.role.dto.Role;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional(readOnly = true,propagation = Propagation.REQUIRED)
public class RoleService {

    @Autowired(required = false)
    private RoleDao roleDao;

    @Autowired(required = false)
    private AuthDao authDao;

    @Transactional(rollbackFor = {Exception.class},propagation = Propagation.REQUIRED)
    public int saveRole(String roleCode,String roleName,String description,int companyid,int level) throws ServiceException,BusinessException{
        if(StringUtils.isBlank(roleCode)){throw new ServiceException("Invalid roleCode!");}
        if(StringUtils.isBlank(roleName)){throw new ServiceException("Invalid roleName!");}
        if(isExistRoleCode(roleCode,companyid)){
            throw new BusinessException("已经存在相同的角色编码！");
        }
        TSysRole role = new TSysRole();
        role.setRoleCode(roleCode);
        role.setRoleName(roleName);
        role.setDescription(description);
        role.setCompanyId(companyid);
        role.setLevel(level);
        roleDao.saveRole(role);
        return role.getRoleId();
    }

    @Transactional(rollbackFor = {Exception.class},propagation = Propagation.REQUIRED)
    public int updateRole(Integer roleId,String roleCode,String roleName,String description,int level,int operatorLevel) throws ServiceException,BusinessException{
        if(StringUtils.isBlank(roleCode)){throw new ServiceException("Invalid roleCode!");}
        if(StringUtils.isBlank(roleName)){throw new ServiceException("Invalid roleName!");}
        if(roleId == null || roleId == 0){throw new ServiceException("Invalid roleId!");}
        if(operatorLevel >= level){
            throw new BusinessException("你可以调整角色等级，但是不能调整到比自己的最大角色等级相同及以上！");
        }

        TSysRole role = roleDao.getTSysRoleById(roleId);
        if(role == null){throw new BusinessException("修改失败，不存在此角色！");}
        if(!roleCode.equals(role.getRoleCode())){
            if(this.isExistRoleCode(roleCode,role.getCompanyId())){
                throw new BusinessException("已经存在相同的角色编码！");
            }
        }
        if(role.getLevel().compareTo(operatorLevel) <= 0){
            throw new BusinessException("你当前的角色等级不具备修改此角色的权限！");
        }

        return roleDao.updateRole(roleId,roleCode,roleName,description);
    }


    public boolean isExistRoleCode(String roleCode,int companyId)throws ServiceException{
        if(StringUtils.isBlank(roleCode)){throw new ServiceException("Invalid roleCode");}
        int result = roleDao.existRoleCode(roleCode,companyId);
        if(result == 0){return false;}
        return true;
    }

    public PageObject<Role> searchRoleLimit(PageObject<Role> rolePageObject,String searchText,int companyId) throws ServiceException{
        int start = PageUtils.getNumberStart(rolePageObject);
        int size = rolePageObject.getRows();
        int total = roleDao.countSearchRole(searchText,companyId);
        List<Role> roleList = roleDao.searchRoleLimit(searchText,start,size,companyId);
        rolePageObject.setTotal(total);
        rolePageObject.setRowsList(roleList);
        return rolePageObject;
    }

    @Transactional(rollbackFor = {Exception.class})
    public int saveRoleAuths(Collection<TSysRoleAuth> roleAuths,int level) throws ServiceException,BusinessException{
        if(roleAuths == null || roleAuths.isEmpty()
                || (roleAuths.size() == 1 && roleAuths.contains(null))){
            throw new ServiceException("roleAuths is blank!");
        }
        Set<Integer> roleIds = new HashSet<Integer>();
        for(TSysRoleAuth roleAuth : roleAuths){
            if(roleAuth.getRoleId()!= null || roleAuth.getRoleId()!= 0) {
                roleIds.add(roleAuth.getRoleId());
            }
        }
        List<TSysRole> roles = roleDao.getRoleByIds(roleIds);
        for(TSysRole role:roles){
            if(role.getLevel().compareTo(level) <= 0){
                throw new BusinessException("没有权限，配置的角色等级不足！");
            }
        }

        for(Integer roleId:roleIds) {
            roleDao.deleteRoleAuthByRoleId(roleId);
        }
        List<TSysAuth> auths = authDao.filterHigherLevel(this.getAuthIds(roleAuths),level);
        if(auths == null || auths.isEmpty() ||
                (auths.size() == 1 && auths.contains(null))){
            return roleDao.addRoleAuth(roleAuths);
        }
        throw new BusinessException("权限等级不足！配置角色的权限中具有超出等级的权限！");
    }

    public Set<Integer> getRoleAuthIdsByRoleId(int roleId)throws ServiceException{
        return roleDao.getRoleAuthIdsByRoleId(roleId);
    }



    public Set<Integer> getAuthIds(Collection<TSysRoleAuth> roleAuths){
        Set<Integer> result = new HashSet<Integer>();
        if(roleAuths == null || roleAuths.isEmpty()){return result;}
        for(TSysRoleAuth roleAuth:roleAuths){
            if(roleAuth == null || roleAuth.getAuthId() == null){
                continue;
            }
            result.add(roleAuth.getAuthId());
        }
        return result;
    }
}
